package madoop.reign;

import java.io.DataInput;
import java.io.DataInputStream;
import java.io.DataOutput;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Timer;
import java.util.TimerTask;


public class Sovereign implements Runnable
{
    ServerSocket  portal;
    List<Mission> missions = new ArrayList<Mission>();
    Platform      platform;
    Timer         timer    = new Timer();


    public Sovereign(Platform platform, int port) throws Exception
    {
        this.portal = new ServerSocket(port);
        this.platform = platform;
        timer.scheduleAtFixedRate(new CleanupTask(), 1000, 30000);
    }


    public void run()
    {
        while (true)
            try {
                accept();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }


    protected void accept() throws Exception
    {
        Socket socket = portal.accept();
        DataInput input = new DataInputStream(socket.getInputStream());
        DataOutput output = new DataOutputStream(socket.getOutputStream());

        String appName = input.readUTF();
        String appClasspath = input.readUTF();
        Application app = new Application(appName, appClasspath);

        Mission mission = new Mission(platform, socket.getLocalPort(), app);
        output.writeInt(socket.getLocalPort());
        socket.close();
        mission.launch();
        missions.add(mission);
    }


    public void cleanup()
    {
        Iterator<Mission> itr = missions.iterator();
        while (itr.hasNext()) {
            if (itr.next().isOver())
                itr.remove();
        }

    }


    public static void main(String[] args) throws Exception
    {
        Properties prop = new Properties();
        prop.load(new FileInputStream(args[0]));
        Platform platform = new Platform(prop);
        Sovereign reign = new Sovereign(platform, Integer.parseInt(args[1]));
        new Thread(reign).start();
    }
    
    
    class CleanupTask extends TimerTask
    {
        public void run()
        {
            cleanup();
        }
    }
}
